package com.markus.code.exam.tencent;

import java.util.*;

/**
 * Author:markusZhang
 * Date:Create in 2020/9/6 20:03
 * todo:
 */
public class Main2 {
    public static class Element<V>{
        V value;
        public Element(V value){
            this.value = value;
        }
    }
    public static class UnionAndSet<V>{
        private HashMap<Element<V>, Element<V>> fatherMap;
        private HashMap<V, Element<V>> elementMap;
        private HashMap<Element<V>,Integer> sizeMap;
        public UnionAndSet(List<List<V>> list){
            this.fatherMap = new HashMap<>();
            this.elementMap = new HashMap<>();
            this.sizeMap = new HashMap<>();
            //初始化集合，每个元素都是一个集合
            for (List<V> vs : list) {
                for (V v : vs) {
                    Element<V> element = new Element<>(v);
                    elementMap.put(v,element);
                    fatherMap.put(element,element);
                    sizeMap.put(element,1);
                }
            }
        }
        //得到两个元素所属集合的头结点
        private Element<V> getHeader(Element<V> element){
            Stack<Element<V>> stack = new Stack<>();
            Element<V> father = fatherMap.get(element);
            while(element != father){
                stack.push(element);//沿途所有节点入栈
                element = father;
                father = fatherMap.get(element);
            }
            //退出循环表示找到头结点了，这时候需要做的事情是将沿途所有节点都指向这个父节点
            while(!stack.isEmpty()){
                fatherMap.put(stack.pop(),father);
            }
            return father;
        }
        //合并两个节点
        public void union(V v1,V v2){
            //合并的前提需要两个元素都存在elementMap里
            if (elementMap.containsKey(v1) && elementMap.containsKey(v2)){
                Element<V> father_v1 = getHeader(elementMap.get(v1));
                Element<V> father_v2 = getHeader(elementMap.get(v2));
                if (father_v1 == father_v2){
                    return ;
                }
                //只有在头节点不同的情况下才进行连通
                Element<V> big = father_v1;
                Element<V> small = father_v2;
                int size_v1 = sizeMap.get(big);
                int size_v2 = sizeMap.get(small);
                big = size_v1 < size_v2 ? small : big;
                small = big==father_v1?father_v2:father_v1;
                int size = sizeMap.get(big)+sizeMap.get(small);
                fatherMap.put(small,big);
                sizeMap.put(big,size);
            }
        }
        public boolean isSameSet(V v1,V v2){
            if (elementMap.containsKey(v1) && elementMap.containsKey(v2)){
                Element<V> header_v1 = getHeader(elementMap.get(v1));
                Element<V> header_v2 = getHeader(elementMap.get(v2));
                return header_v1 == header_v2;
            }
            return false;
        }
        public int getNum(V v){
            if (elementMap.containsKey(v)){
                Element<V> header = getHeader(elementMap.get(v));
                return sizeMap.get(header);
            }
            return 0;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNext()){
            int n = scanner.nextInt();
            int m = scanner.nextInt();
            List<List<Integer>> matrix = new ArrayList<>();
            for (int row = 0;row < m;row++){
                List<Integer> list = new ArrayList<>();
                int count = scanner.nextInt();
                for (int i=0;i<count;i++){
                    list.add(scanner.nextInt());
                }
                matrix.add(list);
            }
            UnionAndSet<Integer> unionAndSet = new UnionAndSet<>(matrix);
            for (int i=0;i<matrix.size();i++){
                List<Integer> list = matrix.get(i);
                for (int j=0;j<list.size()-1;j++){
                    unionAndSet.union(list.get(j),list.get(j+1));
                }
            }
            System.out.println(unionAndSet.getNum(0));
        }
    }
}
